package com.example.lib.muchthread;

/**
 * 对于多个生产者和消费者。为什么要定义while判断标记？
 * 原因：让被唤醒的线程再一次判断标记。
 *
 * 为什么定义notifyAll：
 * 因为需要唤醒对方线程。
 * 如果只用notify，容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
 */

public class p_producer_consumer_146 {
    public static void main(String[] args) {
        Resource146 res = new Resource146();

        Producer146 product = new Producer146(res);
        Consumer146 consumer = new Consumer146(res);

        Thread t1 = new Thread(product);
        Thread t2 = new Thread(product);
        Thread t3 = new Thread(consumer);
        Thread t4 = new Thread(consumer);

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

class Resource146 {
    private String name;
    private int count = 1;
    private boolean flag = false;

    public synchronized void set(String name) {
        while (flag) {
            try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}
        }
        this.name = name + "--" + count++;
        System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
        flag = true;
        this.notifyAll();
    }

    public synchronized void out() {
        while (!flag) {
            try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}
        }
        System.out.println(Thread.currentThread().getName() + "...消费者......"+this.name);
        flag = false;
        this.notifyAll();
    }
}

class Producer146 implements Runnable {

    private Resource146 res;

    public Producer146(Resource146 res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true) {
            res.set("+商品+");
        }
    }
}

class Consumer146 implements Runnable {

    private Resource146 res;

    public Consumer146(Resource146 res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true) {
            res.out();
        }
    }
}
